package util;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.util.DigestUtils;

import constant.Constant;


/**
 * 
 * Util
 * @version 1.0.0
 * 
 */
public class Util {

  public static final String SEPARATOR_SEMICOLON = ";";
  public static final String SEPARATOR_EQUEST = "=";
  public static final String ROWSTART = "rowStart";
  public static final String ROWEND = "rowEnd";
  public static final String ORDERBY = "orderBy";
  public static final String ORDER = "order";
  public static final String LOCK = "LOCK";

  private static final String FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";
  private static final ThreadLocal<SimpleDateFormat> format = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected synchronized SimpleDateFormat initialValue() {
      return new SimpleDateFormat(FORMAT_STRING);
    };
  };

  /**
   * getKey 生成缓存KEY KEY命名规则 类名+方法名+参数名称:参数值 <br>
   * (例如：ClassSimpleNameMethedNameParamParamsValue)
   * 
   * @param params 参数Map 必填
   * @param throwable 必填
   * @return String MemcacheKey
   * @exception
   * @since 1.0.0
   */
  public static String getKey(Map<String, Object> params, Throwable throwable) {
    if (throwable == null || params == null)
      return null;
    // 类名称
    String className = throwable.getStackTrace()[0].getClassName();
    // 方法名称
    String methodName = throwable.getStackTrace()[0].getMethodName();

    StringBuffer sb = new StringBuffer();
    sb.append(className.substring(className.lastIndexOf(".") + 1));
    sb.append(methodName);

    for (String key : params.keySet()) {
      Object o = params.get(key);
      // System.out.println("=====================value:=======================" + o);
      sb.append(key + o);
    }

    String oldKey = sb.toString().replace(" ", "");
    return DigestUtils.md5DigestAsHex(oldKey.getBytes());
  }

  /**
   * getLock(取得缓存锁名) <br>
   * (生成缓存LOCK LOCK命名规则 LOCK_MEMCACHEDKEY)
   * 
   * @param memcachedKey
   * @return String
   * @exception
   * @since 1.0.0
   */
  public static String getLock(String memcachedKey) {
    return LOCK + memcachedKey;
  }

  /**
   * convertParams(转换为Map参数)
   * 
   * @param source PO对象
   * @param params 参数Map void
   * @exception
   * @since 1.0.0
   */
  public static void convertParams(Object source, Map<String, Object> params) {
    if (source == null || params == null) {
      return;
    }
    convertParams(source, params, source.getClass(), false);
  }

  public static void convertNotEmptyParams(Object source, Map<String, Object> params) {
    if (source == null || params == null) {
      return;
    }
    convertParams(source, params, source.getClass(), true);
  }

  /**
   * 
   * getPageParames(取得页面参数)
   * 
   * @param page Page对象 非空
   * @param parames 参数Map 非空
   * @exception
   * @since 1.0.0
   */
  public static void getPageParames(final Page<?> page, Map<String, Object> parames) {
    if (parames == null || page == null) {
      return;
    }

    if (page.getFirst() >= 0) {
      parames.put(ROWSTART, page.getFirst());
      parames.put(ROWEND, page.getPageSize() + page.getFirst());
    }

    if (page.getOrderBy() != null) {
      parames.put(ORDERBY, page.getOrderBy());
      String order = page.getOrder();
      if (order == null) {
        order = Page.DESC;
      }
      parames.put(ORDERBY, page.getOrderBy());
      parames.put(ORDER, order);
    }
  }

  /**
   * 
   * convertMemcacheKey(转换MemcacheKey)<br>
   * 此方法在service中直接调用有问题，暂时不用了。update by dzh <br>
   * 
   * @see Util#getKey
   * 
   * @param source po对象 非空
   * @param throwable 非空
   * @return String
   * @exception
   * @since 1.0.0
   */
  @Deprecated
  public static String convertMemcacheKey(Object source, Throwable throwable) {
    if (source == null || throwable == null) {
      return null;
    }

    StringBuffer sb = new StringBuffer();
    Class<?> c = source.getClass();

    String sqlMapId = ClassUtils.getSQLMapId(c, throwable);
    sb.append(sqlMapId);
    sb.append(SEPARATOR_SEMICOLON);

    for (Field field : c.getDeclaredFields()) {
      try {
        field.setAccessible(true);
        String fieldName = field.getName();
        Type type = field.getGenericType();
        Object value = field.get(source);

        if (value == null) {
          continue;
        } else if (type.equals(String.class)) {
          addParame(sb, fieldName, (String) value);
        } else if (type.equals(Long.class)) {
          addParame(sb, fieldName, String.valueOf(value));
        } else if (type.equals(Date.class)) {
          addParame(sb, fieldName, format.get().format((Date) value));
        } else if (type.equals(BigDecimal.class)) {
          BigDecimal bigDecimal = ((BigDecimal) value);
          addParame(sb, fieldName, String.valueOf(bigDecimal.doubleValue()));
        }
      } catch (Exception e) {
        LoggerUtils.errorInfo("convertMemcacheKey出错啦", e);
      }
    }
    return sb.substring(0, sb.length() - 1);
  }

  private static void addParame(StringBuffer sb, String fieldName, String value) {
    sb.append(fieldName);
    sb.append(SEPARATOR_EQUEST);
    sb.append(value);
    sb.append(SEPARATOR_SEMICOLON);
  }

  /**
   * getCharConversion(编码格式转换) (这里描述这个方法适用条件 – 可选)
   * 
   * @param str1
   * @param str2
   *        void
   * @exception
   * @since 1.0.0
   */
  public static String getCharConversion(String str, String source, String target) {
    try {
      return new String(str.getBytes(source), target);
    } catch (Exception e) {
      return str;
    }
  }

  private static void convertParams(Object source, Map<String, Object> params, Class<?> c, boolean notEmpty) {
    Class<?> s = c.getSuperclass();
    if (s != null) {
      if (s.equals(Object.class) == false) {
        convertParams(source, params, s, notEmpty);
      }
    }
    for (Field field : c.getDeclaredFields()) {
      field.setAccessible(true);
      Object fieldval = null;
      try {
        fieldval = field.get(source);
      } catch (IllegalArgumentException e) {
        LoggerUtils.errorInfo(e.getMessage(), e);
      } catch (IllegalAccessException e) {
        LoggerUtils.errorInfo(e.getMessage(), e);
      }
      if (fieldval != null && "serialVersionUID".equals(field.getName()) == false
          && "this$0".equals(field.getName()) == false) {
        String tmp = String.valueOf(fieldval);
        if (notEmpty == false || StringUtils.isNotEmpty(tmp)) {
          if (field.getGenericType().equals(Date.class)) {
            params.put(field.getName(), format.get().format((Date) fieldval));
          } else {
            params.put(field.getName(), fieldval);
          }
        }
      }
    }
  }

  /**
   * addParams(添加参数) (这里描述这个方法适用条件 – 可选)
   * 
   * @param params
   * @param key
   * @param value
   *        void
   * @exception
   * @since 1.0.0
   */
  public static void addParams(Map<String, Object> params, String key, String value) {
    if (value != null && value.length() > 0) {
      params.put(key, value);
    }

  }

  /**
   * stirngToBigDecimal(String转BigDecimal)
   * 
   * @param tag
   *        void
   * @exception
   * @since 1.0.0
   */
  public static BigDecimal stirngToBigDecimal(String tag) {
    if (StringUtils.isBlank(tag)) {
      return new BigDecimal(0);
    }
    return new BigDecimal(tag);
  }

  /**
   * 验证是否是数字 isNumeric
   * 
   * @param str
   * @return boolean
   * @exception
   * @since 1.0.0
   */
  public static boolean isNumeric(String str) {
    if (StringUtils.isNotBlank(str)) {
      for (int i = str.length(); --i >= 0;) {
        int chr = str.charAt(i);
        if (chr < 48 || chr > 57)
          return false;
      }
      return true;
    }
    return false;
  }

  /**
   * removeStringSign(如果当前字符串不为空，去掉最后一个字符)
   * 
   * @param str
   * @return
   *         String
   * @exception
   * @since 1.0.0
   */
  public static String removeStringSign(String str) {
    if (StringUtils.isBlank(str)) {
      return str;
    }
    return str.substring(0, str.length() - 1);
  }

  /**
   * 删除Map中值为空的属性值
   * mapIsNotBlankParams
   * 
   * @param params
   * @return Map<String,Object>
   * @exception
   * @since 1.0.0
   */
  public static Map<String, Object> mapIsNotBlankParams(Map<String, Object> params) {
    if (params != null && params.size() > 0) {
      Map<String, Object> newMap = new HashMap<String, Object>();
      Iterator<?> iterator = params.keySet().iterator();
      while (iterator.hasNext()) {
        String key = String.valueOf(iterator.next());
        Object valeObject = params.get(key);
        String value = valeObject != null ? valeObject.toString() : null;
        // List 类型
        if (valeObject instanceof List) {
          List<?> list = (List<?>) valeObject;
          if (list != null && list.size() > 0) {
            newMap.put(key, valeObject);
          }
        }
        // String 类型
        else if (valeObject instanceof String) {
          if (StringUtils.isNotBlank(value)) {
            newMap.put(key, value);
          }
        }
        // Long 类型
        else if (valeObject instanceof Long) {
          if (StringUtils.isNotBlank(value)) {
            newMap.put(key, Long.valueOf(value));
          }
        }
        // Integer 类型
        else if (valeObject instanceof Integer) {
          if (StringUtils.isNotBlank(value)) {
            newMap.put(key, Integer.valueOf(value));
          }
        }
        // Date 类型
        else if (valeObject instanceof Date) {
          if (value != null) {
            newMap.put(key, valeObject);
          }
        } else {
          if (StringUtils.isNotBlank(value)) {
            newMap.put(key, valeObject);
          }
        }

      }
      return newMap;
    }
    return params;
  }

  /**
   * stringToNull(处理字符串，如果是null, 返回"")
   * 
   * @param str
   * @return String
   * @exception
   * @since 1.0.0
   */
  public static String stringToNull(String str) {
    if (str == null) {
      return "";
    }else if (str.equals("null")) {
    	return "";
	}
    return str;
  }

  

  /***
   * 替换字符串 将 \n 替换 <br>
   * stringReplace
   * 
   * @param value
   *        void
   * @return
   * @exception
   * @since 1.0.0
   */
  public static String stringReplace(String value, String tagV) {
    String temp = "";
    try {
      if (StringUtils.isNotBlank(value)) {
        temp = value.replaceAll("\n", tagV);
      }
    } catch (Exception e) {
      temp = value;
    }

    return temp;
  }

 

  public static String[] poToTableName(String poName) {
    StringBuffer tables = new StringBuffer();
    if (StringUtils.isNotBlank(poName)) {
      String tableTemp = "";
      for (int i = 0; i < poName.length(); i++) {
        char c = poName.charAt(i);
        int k = (int) c;
        // 判断是否是大写字母,首字母大写除外
        if (k >= 65 && k <= 90 && i > 0) {
          tableTemp += "_" + c;
        } else {
          tableTemp += c;
        }
      }
      tables.append("SYS_" + tableTemp.toUpperCase() + "_ALL").append(",");
      tables.append("AE_" + tableTemp.toUpperCase() + "_ALL").append(",");
      tables.append("SMS_" + tableTemp.toUpperCase() + "_ALL");
      return tables.toString().split(",");
    }
    return null;
  }
}
